package org.game.gobang.server.handler;

import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.game.model.Click;
import org.game.model.Heartbeat;
import org.game.model.JoinRoom;
import org.game.result.RestResult;
import org.game.result.RestResultBuilder;
import org.game.result.ResultCode;
import org.game.util.JsonUtil;
import org.game.util.MapUtil;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class CustomizeServerHandler extends GobangServerHandler {
    @Override
    protected void test(ChannelHandlerContext ctx, Object value) {
        System.out.println(value);
    }

    @Override
    protected void heartbeat(ChannelHandlerContext ctx, Object value) {
        System.out.println("ping with " + ctx.channel());
        RestResult restResult = new RestResultBuilder().success(
                Heartbeat.builder().msg("pong").build());
        ctx.writeAndFlush(JsonUtil.toJson(restResult));
    }

    @Override
    protected void createRoom(ChannelHandlerContext ctx, Object value) {
        getRooms().put((String) value, new ConcurrentHashMap<>());
        getRooms().get(value).put(ctx, "");
        getUsers().put(ctx, (String) value);
        allRooms(ctx, value);
        joinRoom(ctx, value);
    }

    @Override
    protected void allRooms(ChannelHandlerContext ctx, Object value) {
        Map<String, Integer> room = new HashMap<>();

        getRooms().forEach((k, v) -> {
            room.put(k, v.size());
        });

        RestResult restResult = new RestResultBuilder().success(ResultCode.ALL_ROOMS);
        restResult.setData(room);

        ctx.writeAndFlush(JsonUtil.toJson(restResult));
    }

    @Override
    protected void joinRoom(ChannelHandlerContext ctx, Object value) {
        getRooms().get(value).put(ctx, "");
        getUsers().put(ctx, (String) value);

        RestResult restResult = new RestResultBuilder().success(ResultCode.JOIN_ROOM);
        restResult.setData(JoinRoom
                .builder()
                .name((String) value)
                .color(getRooms().get(value).size() == 1 ? "#7c191e": "#c35c5d")
                .player(String.valueOf(getRooms().get(value).size()))
                .build());

        ctx.writeAndFlush(JsonUtil.toJson(restResult));
    }

    @Override
    protected void click(ChannelHandlerContext ctx, Object value) {
        String name = getUsers().get(ctx);

        getRooms().get(name).forEach((k, v) -> {
            if (k == ctx) {
                return;
            }

            RestResult restResult = new RestResultBuilder().success(ResultCode.CLICK);
            restResult.setData(value);
            k.writeAndFlush(JsonUtil.toJson(restResult));
        });
    }

    @Override
    protected void win(ChannelHandlerContext ctx, Object value) {
        String name = getUsers().get(ctx);

        getRooms().get(name).forEach((k, v) -> {
            if (k == ctx) {
                return;
            }

            RestResult restResult = new RestResultBuilder().success(ResultCode.WIN);
            restResult.setData(value);
            k.writeAndFlush(JsonUtil.toJson(restResult));
        });
    }
}
